package com.lzh.others.basejava.IO_18;


import com.sun.istack.internal.NotNull;

import java.io.File;
import java.io.FilenameFilter;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

public final class Directory {
    public static File[] local(File dir, String regex) {
        return dir.listFiles(new FilenameFilter() {
            private Pattern pattern = Pattern.compile(regex);

            @Override
            public boolean accept(File dir, String name) {
                return pattern.matcher(new File(name).getName()).matches();
            }
        });
    }

    public static File[] local(String path, String regex) {
        //Overloaded
        return local(new File(path), regex);
    }

    public static class TreeInfo implements Iterable<File> {
        public List<File> files = new ArrayList<>();
        public List<File> dirs = new ArrayList<>();

        @NotNull
        @Override
        public Iterator<File> iterator() {
            return files.iterator();
        }

        void addAll(TreeInfo other) {
            files.addAll(other.files);
            dirs.addAll(other.dirs);
        }

        @Override
        public String toString() {
            return "dirs: " + PPrint.pformat(dirs) + "\n\nfiles: " + PPrint.pformat(files);
        }

    }

    public static TreeInfo walk(String start, String regex) {
        //Begin recursion
        return recurseDirs(new File(start), regex);
    }

    public static TreeInfo walk(File start, String regex) {
        //Overloaded
        return recurseDirs(start, regex);
    }

    public static TreeInfo walk(String start) {
        //Everything
        return recurseDirs(new File(start), ".*");
    }

    static TreeInfo recurseDirs(File startDir, String regex) {
        TreeInfo result = new TreeInfo();
        if (startDir != null && startDir.listFiles() != null) {
            for (File item : startDir.listFiles()) {
                if (item.isDirectory()) {
                    result.dirs.add(item);
                    result.addAll(recurseDirs(item, regex));
                } else {
                    if (item.getName().matches(regex)) {
                        result.files.add(item);
                    }
                }
            }
        }
        return result;
    }

    public static void main(String[] args) {
        Class<?> clazz = Directory.class;
        URL resource = clazz.getResource(clazz.getSimpleName() + ".class");
        File path = new File(resource.getPath()).getParentFile();
        System.out.println(Arrays.stream(local(path, "DirList.class")).map(File::getName).collect(Collectors.joining(",")));
        System.out.println("packageDir = " + path.getAbsolutePath());
        System.out.println(walk(path, ".*"));
    }
}
